package com.sdp.wz.db.wz_serial_code.service.impl;

import java.time.LocalDate;
import java.util.concurrent.TimeUnit;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sdp.core.bizc.utils.ApplicationContextUtils;
import com.sdp.wz.db.wz_serial_code.entity.WzSerialCode;
import com.sdp.wz.db.wz_serial_code.mapper.WzSerialCodeMapper;
import com.sdp.wz.db.wz_serial_code.service.IWzSerialCodeService;
import com.sdp.wz.utils.LocalDateUtil;
import com.sdp.wz.utils.WzConstants;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zsp
 * @since 2024-01-16
 */
@Service
public class WzSerialCodeServiceImpl extends ServiceImpl<WzSerialCodeMapper, WzSerialCode> implements IWzSerialCodeService {

	@Autowired
	private RedissonClient redissonClient;
	
	@Override
	public String createSerialCode(String codePrefix) {
		if(StringUtils.isEmpty(codePrefix)) {
			return null;
		}
		String serialCode = null;
		RLock lock = null;
		if(WzConstants.流水号前缀_物资采购单.getCode().equals(codePrefix)) {
			lock = redissonClient.getLock(WzConstants.采购单号REDIS锁名.getCode());
		}else if(WzConstants.流水号前缀_物资到货单.getCode().equals(codePrefix)) {
			lock = redissonClient.getLock(WzConstants.到货单号REDIS锁名.getCode());
		}else if(WzConstants.流水号前缀_物资检验单.getCode().equals(codePrefix)) {
			lock = redissonClient.getLock(WzConstants.检验单号REDIS锁名.getCode());
		}else if(WzConstants.流水号前缀_物资入库单.getCode().equals(codePrefix)) {
			lock = redissonClient.getLock(WzConstants.入库单号REDIS锁名.getCode());
		}else if(WzConstants.流水号前缀_物资出库单.getCode().equals(codePrefix)) {
			lock = redissonClient.getLock(WzConstants.出库单号REDIS锁名.getCode());
		}else if(WzConstants.流水号前缀_物资盘存单.getCode().equals(codePrefix)) {
			lock = redissonClient.getLock(WzConstants.盘存单号REDIS锁名.getCode());
		}
		if(lock==null) {
			return null;
		}
		try {
			if (lock.tryLock(3, TimeUnit.SECONDS)) {
				serialCode = ApplicationContextUtils.getBean(WzSerialCodeServiceImpl.class).getCode(codePrefix);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} finally {
			lock.unlock();
		}
		return serialCode;
	}
	
	@Transactional(rollbackFor=Exception.class,propagation=Propagation.REQUIRES_NEW)
	private String getCode(String codePrefix) {
		String nowMonthStr = LocalDateUtil.localDate2String(LocalDate.now(),"yyyy-MM");
		LocalDate nowMonth = LocalDateUtil.String2LocalDate(nowMonthStr+"-01");
		LambdaQueryWrapper<WzSerialCode> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(WzSerialCode::getRepairMonth, nowMonth);
		queryWrapper.eq(WzSerialCode::getCodePrefix, codePrefix);
		WzSerialCode wzSerialCode = getOne(queryWrapper,false);
		if(StringUtils.isEmpty(wzSerialCode)) {
			wzSerialCode = new WzSerialCode();
			wzSerialCode.setRepairMonth(nowMonth);
			wzSerialCode.setRepairDate(LocalDate.now());
			wzSerialCode.setSerialCode(1);
			wzSerialCode.setCodePrefix(codePrefix);
			save(wzSerialCode);
		}else {
			wzSerialCode.setSerialCode(wzSerialCode.getSerialCode()+1);
			updateById(wzSerialCode);
		}
		String str = String.valueOf(wzSerialCode.getSerialCode());
		int len = str.length();
		if (len >= 4) {
			return str;
		}
		int rest = 4 - len;
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < rest; i++) {
			sb.append('0');
		}
		sb.append(str);
		sb.insert(0, codePrefix+nowMonthStr.replace("-", "")+"-");
		return sb.toString();
	}

}
